# 剑指Offer题解 - Day56
# 剑指 Offer 29. 顺时针打印矩阵
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
1
2
2
限制:
0 <= matrix.length <= 100
0 <= matrix[i].length <= 100
思路:
按照题目描述,我们需要顺时针打印矩阵中的每个数字。而顺时针打印遵循**“从左向右、从上向下、从右向左、从下向上”**的规律。
我们维护上右下左四个边界,每打印一边,就将边界往相反方向缩进一行。具体来说,
- 打印上边界所处行之后,将上边界向下缩进;
- 打印右边界所处列之后,将右边界向左缩进;
- 打印下边界所处行之后,将下边界向上缩进;
- 打印左边界所处列之后,将左边界向右缩进;
- 直到某一个边界越过了相对边界,则停止循环。
# 模拟
/**
* @param {number[][]} matrix
* @return {number[]}
*/
var spiralOrder = function(matrix) {
if(!matrix.length) return []; // 空矩阵返回空数组
let l = 0; // 初始化四边的边界
let r = matrix[0].length - 1;
let t = 0;
let b = matrix.length - 1;
let x = 0; // 初始化结果数组的索引
let res = []; // 初始化结果数组
while(true) {
for (let i = l; i <= r; i++) res[x++] = matrix[t][i];
if (++t > b) break;
for (let i = t; i <= b; i++) res[x++] = matrix[i][r];
if (l > --r) break;
for (let i = r; i >= l; i--) res[x++] = matrix[b][i];
if (t > --b) break;
for (let i = b; i >= t; i--) res[x++] = matrix[i][l];
if (++l > r) break;
}
return res;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
- 时间复杂度 O(mn)。
- 空间复杂度 O(1)。
分析:
有几个点需要注意。初始化右边界和下边界的值,需要矩阵内层和外层的长度减一。给结果数组赋值的时候,通过x++
达到了先赋值再索引加一的效果。
判断越界条件通过先自增或自减,再判断是否越界。就可以将边界缩进的同时判断越界情况。
最终返回结果数组即可。
# 总结
本题考查矩阵打印的模拟。难点在于边界情况的考虑与循环的终止。
复杂度方面,由于需要遍历矩阵所有的节点,因此时间复杂度是O(mn)
。声明变量占用常数级别的空间。